
import os
import os.path
from whiff import resolver
from whiff.middleware import Eval
from whiff.middleware import misc
from whiff import whiffenv

#def prefixExists(inDirectory, filePrefix):
#    ls = os.listdir(inDirectory)
#    for fn in ls:
#        if fn.startswith(filePrefix):
#            return inDirectory+"/"+fn
#    return False

#def is_redirected(app):
#    # XXXXXX this is a hack
#    if isinstance(app, resolver.listingRedirect):
#        return True
#    if isinstance(app, resolver.WsgiApplicationWrapper) and isinstance(app.wsgi_callable, resolver.listingRedirect):
#        return True
#    return False

def trim(filename):
    while filename.startswith("/"):
        filename = filename[1:]
    return "/"+filename

def httpjoin(directoryname, filename):
    while directoryname.endswith("/"):
        directoryname = directoryname[:-1]
    filename = trim(filename)
    return trim(directoryname+filename)

def contentLink(path, body):
    return """<a href="%s">%s</a>""" % (trim(path+"/index"), body)

class DynamicTreeDictionary(misc.utility):
    def __init__(self, urlPrefixForRoot, env):
        self.env = env
        self.urlPrefix = trim(urlPrefixForRoot)
        self.itemCache = {}
    def __getitem__(self, httppath):
        if httppath.endswith("/index"):
            httppath = httppath[:-6]
        httppath = trim(httppath)
        #pr "getting tree info for httppath", httppath
        test = self.itemCache.get(httppath)
        if test is not None:
            return test # cached result
        assert httppath.find("..")<0, "relative paths not permitted: "+repr(path)
        urlPrefix = self.urlPrefix
        if not httppath.startswith(urlPrefix):
            raise KeyError, "path must match prefix "+repr((httppath, urlPrefix))
        suffix = httppath[len(urlPrefix):]
        while suffix.startswith("/"):
            suffix = suffix[1:]
        parent = None
        if suffix:
            (parent, dummy) = os.path.split(httppath)
        D = {}        
        childrenData = self.childrenData(httppath)
        body = childrenData.get("summary", repr(suffix))
        children = childrenData.get("children")
        D["body"] = contentLink(httppath, body)
        if parent:
            D["parent"] = trim(parent+"/index")
        if children:
            D["children"] = [httpjoin(httppath, c+"/index") for c in children]
        #pr "returning info dict", (httppath, D)
        self.itemCache[httppath] = D
        return D
    # the following doesn't work because the environment gets confused (I think)
    #def childrenData(self, httppath):
    #    fragmenturl = httpjoin(httppath, "/_children")
    #    root = self.env[whiffenv.ROOT]
    #    try:
    #        (app, responding_path, path_remainder) = root.resolve(fragmenturl)
    #        print "for", repr(fragmenturl), "app", (app, responding_path, path_remainder)
    #        #if not responding_path or not responding_path[-1]=="_children":
    #        #    raise KeyError, "redirected for "+repr(fragmenturl)
    #        if is_redirected(app):
    #            raise KeyError, "redirected for "+repr(fragmenturl)
    #        content = self.param_json(app, self.env)        
    #        print "for", repr(fragmenturl), "got", repr(content)
    #    except resolver.ModuleRootResolutionException:
    #        raise KeyError, "no such child "+repr(fragmenturl)
    #    return content
    def childrenData(self, httppath):
        if httppath.find("__whiff_directory_listing__")>=0:
            raise KeyError, "no child found for directory listing "+repr(httppath)
        fragmenturl = httpjoin(httppath, "/_children")
        template = """ {{include "%s"/}} """ % fragmenturl
        #pr "eval template", repr(template)
        try:
            app = Eval.__middleware__(template)
            content = self.param_json(app, self.env)        
        except resolver.ModuleRootResolutionException:
            raise KeyError, "no such child "+repr(httppath)
        return content

class TreeFinder:
    def __init__(self, urlPrefixForRoot, env=None):
        self.urlPrefix = urlPrefixForRoot
        self.env = env
    def localize(self, env):
        return TreeFinder(self.urlPrefix, env.copy())
    def get(self, pathlist):
        assert len(pathlist)==0, "no path information expected for tree finder "+repr(pathlist)
        return DynamicTreeDictionary(self.urlPrefix, self.env)
